package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.model.ObjectListing;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.base.PageResponse;
import com.zzyl.dto.CustomerUserLoginDto;
import com.zzyl.entity.Contract;
import com.zzyl.entity.Elder;
import com.zzyl.entity.Member;
import com.zzyl.entity.Order;
import com.zzyl.exception.BusinessException;
import com.zzyl.mapper.ContractMapper;
import com.zzyl.mapper.ElderMapper;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.mapper.OrderMapper;
import com.zzyl.properties.JwtProperties;
import com.zzyl.properties.WechatConfigProperties;
import com.zzyl.service.MemberService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import com.zzyl.vo.MemberVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
    private static List<String> DEFAULT_NICKNAME_PREFIX = List.of("生活更美好", "大桔大利", "日富一日", "好柿开花", "柿柿如意", "一椰暴富", "大柚所为", "杨梅吐气", "天生荔枝");

    @Autowired
    private WechatConfigProperties wechatConfigProperties;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public LoginVo login(CustomerUserLoginDto customerUserLoginDto) {
        //1.向官方微信发送请求。获取openid
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid",wechatConfigProperties.getAppid());
        paramMap.put("secret",wechatConfigProperties.getSecret());
        paramMap.put("js_code",customerUserLoginDto.getCode());
        paramMap.put("grant_type","authorization_code");
        String result = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session", paramMap);
        Map<String,String> map = JSON.parseObject(result, Map.class);
        String openid = map.get("openid");
        if (StrUtil.isEmpty(openid)){
            throw new BusinessException("登陆失败");
        }

        //2.从微信官方获取手机号
        //2-1 获取token
        Map<String, Object> paramMap1 = new HashMap<>();
        paramMap1.put("appid",wechatConfigProperties.getAppid());
        paramMap1.put("secret",wechatConfigProperties.getSecret());
        paramMap1.put("grant_type","client_credential");
        String result1 = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", paramMap1);
        Map<String,String> map1 = JSON.parseObject(result1, Map.class);
        String accessToken = map1.get("access_token");
        if (StrUtil.isEmpty(accessToken)){
            throw new BusinessException("登陆失败");
        }

        //获取手机号
        Map<String, Object> paramMap2 = new HashMap<>();
        paramMap2.put("code", customerUserLoginDto.getPhoneCode());
        String result2 = HttpUtil.post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken, JSON.toJSONString(paramMap2));
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(result2);
        JSONObject phone_info = jsonObject.getJSONObject("phone_info");
        String phoneNumber = phone_info.getString("phoneNumber");

        //查询数据库中memberr是否存在这个openid
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Member::getOpenId,openid);
        Member member = memberMapper.selectOne(wrapper);
        if (member == null){
            //这个member数据库中不存在，添加到数据库中
            member = new Member();
            String phone = phoneNumber.toString();
            member.setPhone(phone);
            member.setOpenId(openid);
            member.setName(RandomUtil.randomEle(DEFAULT_NICKNAME_PREFIX)+phone.substring(7,11));

            memberMapper.insert(member);
        }else {
            //已经存在，老用户更新一下手机号
            member.setPhone(phoneNumber.toString());
            memberMapper.updateById(member);
        }


        //生成token返回
        Map<String, Object> claims = new HashMap<>();
        claims.put("userid", member.getId());
        claims.put("sub", member.getName());

        String jwt = JwtUtil.createJWT(jwtProperties.getBase64EncodedSecretKey(), jwtProperties.getTtl(), claims);

        //组装返回结果
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(jwt);
        loginVo.setNickName(member.getName());

        return loginVo;
    }

    @Override
    public PageResponse<MemberVo> findByIdPage(String nickname, String phone , Integer pageNum , Integer pageSize) {
        //1.分页
        Page<Member> page = new Page<>(pageNum,pageSize);

        //2.设置业务条件
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotEmpty(nickname),Member::getName,nickname)
                .like(StrUtil.isNotEmpty(phone),Member::getPhone,phone);

        //分页查询
        Page<Member> memberPage = getBaseMapper().selectPage(page, wrapper);

        List<MemberVo> memberVoList = memberPage.getRecords().stream().map(member -> {
            //1.复制
            MemberVo memberVo = BeanUtil.copyProperties(member, MemberVo.class);
            //老人姓名

            List<Elder> list = elderMapper.findByMemberId(memberVo.getId());
            if (CollUtil.isNotEmpty(list)) {
                String names = list.stream().map(elder -> {
                    return elder.getName();
                }).collect(Collectors.joining(","));
                memberVo.setElderNames(names);
            }

            //是否签约
            LambdaQueryWrapper<Contract> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Contract::getMemberPhone, memberVo.getPhone())
                    .eq(Contract::getStatus, 1);
            Long count1 = contractMapper.selectCount(wrapper1);
            memberVo.setIsSign(count1 > 0 ? "是" : "否");


            //下单次数
            //select count(*) from app_order where member_id = and payment_status = 2 and status = 3
            LambdaQueryWrapper<Order> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(Order::getMemberId, memberVo.getId())
                    .eq(Order::getPaymentStatus, 2)
                    .eq(Order::getStatus, 3);
            Long count2 = orderMapper.selectCount(wrapper2);
            memberVo.setOrderCount(count2.intValue());
            return memberVo;

        }).collect(Collectors.toList());


        return new PageResponse<>(page,memberVoList);
    }
}
